/*
 * proocess.c
 *
 *  Created on: 2023年12月25日
 *      Author: Administrator
 */


#include "process.h"
#include "usart.h"
//开启打印标志
uint8_t priFlag = 0;
typedef  void (*pFunction)(void);

static cmdStruct_t cmdStruct;
static replyStruct_t replyStruct;

system_para_t system_para;


uint8_t iapbuf[2048]; 	//2K字节缓存

static uint64_t ulBufFlashApp [ 256 ];

uint16_t fastdds_cmd[][CMD_MAX]=
{
	{IAP_VERSION			,5,0,0,0  },//查询软件版本
	{IAP_START				,5,0,1,4  },//开始固件更新
	{IAP_SENDDATA			,5,0,2,0  },//固件更新数据传输
	{IAP_OVER				,5,0,3,0  },//固件更新结束
	{IAPR_ERR				,5,0,4,0  },//固件更新错误
	{IAP_LOG				,5,0,5,0  },//固件更新消息
	{IAP_BOOT				,5,0,6,0  },//固件更新状态保持
	{IAP_RESET				,5,0,7,0  },//软复位

};

typedef void(*process_cmd_decode)(cmdStruct_t *suite);
/*跳转表*/
const process_cmd_decode process_decode_table[]=
{
	process_iap_version,
	process_iap_start,
	process_iap_senddata,
	process_iap_over,
	process_iap_err,
	process_iap_log,
	process_iap_boot,
	process_iap_reset,

};

static const unsigned int crc32tab[] = {
 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};

// 计算Modbus CRC-16校验值
uint16_t calculateModbusCRC16(uint8_t *data, uint32_t length) {
    uint16_t crc = 0xFFFF;

    for (int i = 0; i < length; i++) {
        crc ^= data[i];

        for (int j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;  // 0xA001 是CRC-16的多项式
            } else {
                crc = crc >> 1;
            }
        }
    }

    return crc;
}

uint8_t Check_ModbusCRC16(cmdStruct_t *suite)
{
	uint8_t ret = 0;
	uint16_t crc16_cal_value = 0,crc16_rx_value = 0;


	crc16_rx_value = suite->m_Message[suite->m_DataLen] + suite->m_Message[suite->m_DataLen+1]*0x100;

	crc16_cal_value = calculateModbusCRC16( (uint8_t *)suite, suite->m_DataLen + 12 );

	if(crc16_cal_value != crc16_rx_value)
			ret = 0x01;//校验失败

	return ret;
}

static void frame_header_fill(cmdStruct_t *suite,uint32_t data_len)
{
    replyStruct.m_DevType          = suite->m_DevType;  //m_DevType
    replyStruct.m_SrcDevType       = suite->m_DstDevType;        //m_SrcDevType 回包：源组件 目标组件  对调
    replyStruct.m_SrcDevNum        = suite->m_DstDevNum;        //m_SrcDevNum
    replyStruct.m_DstDevType       = suite->m_SrcDevType;        //m_DstDevType
    replyStruct.m_DstDevNum        = suite->m_SrcDevNum;        //m_DstDevNum
    replyStruct.m_CmdType          = suite->m_CmdType;                //m_CmdType
    replyStruct.m_CmdChildType     = suite->m_CmdChildType;        //m_CmdChildType
    replyStruct.m_devState         = 0;                                 //m_devState
    replyStruct.m_DataLen          =  data_len;                 //m_DataLen

}

/*
函数功能:按协议应答数据
输入参数:
输出参数:无
*/
#define ENABLED_MODBUSCRC16  1

void etwsSendto(uint8_t *data,uint32_t len)
{
    uint8_t size_crc = 0;
	uint32_t sendLen = 0;

#if(ENABLED_MODBUSCRC16)
             uint16_t crc16_tx_value = 0;
			 crc16_tx_value = calculateModbusCRC16(data, len);
			 *(data + len) = crc16_tx_value & 0xff;
			 *(data + len + 1) = (crc16_tx_value>>8) & 0xff;
			 size_crc = 2;
#endif

     sendLen = len + size_crc;
	HAL_UART_Transmit(&huart4,data,sendLen,0xffff);
}


/*************************************Iap_main**************************************/

void process_iap_version(cmdStruct_t *suite)
{
	//暂时没用到，只是告诉上位机，进入了boot模式
	system_para.boot = 1;
	frame_header_fill(suite,4);
	replyStruct.m_Message[0] 	= BOOTLOADER_STATE;//固件更新
	replyStruct.m_Message[1] 	= 0x01;//版本V1.0.0
	replyStruct.m_Message[2] 	= 0x00;
	replyStruct.m_Message[3]		= 0x00;
	etwsSendto((uint8_t *)&replyStruct,replyStruct.m_DataLen+12);
}

void process_iap_start(cmdStruct_t *suite)
{
	//第二阶段，可以进行固件更新
	system_para.boot = 1;
	uint32_t size = 0;
	uint32_t crc32;
	size = (suite->m_Message[0] << 0) |
			(suite->m_Message[1] << 8) |
			(suite->m_Message[2] << 16) |
			(suite->m_Message[3] << 24) ;
	crc32 = (suite->m_Message[4] << 0) |
			(suite->m_Message[5] << 8) |
			(suite->m_Message[6] << 16) |
			(suite->m_Message[7] << 24) ;
	system_para.size = size;
	system_para.crc32 = crc32;

	replyStruct.m_DataLen = 8;

	memcpy(replyStruct.m_Message,suite->m_Message,replyStruct.m_DataLen);
	frame_header_fill(suite,replyStruct.m_DataLen);

	etwsSendto((uint8_t *)&replyStruct,replyStruct.m_DataLen+12);

}
//将校验成功的APP数据从DownLoad区拷贝到APP区
void iap_appbin_swap(uint32_t appAddr,uint32_t downloadAddr,uint32_t size)
{
	uint32_t num=0,i,j=0;
	uint32_t swapApp = appAddr,swapDownload = downloadAddr;
	uint64_t *pData = (uint64_t *)iapbuf;
	num = (size % STM_SECTOR_SIZE > 0)?((size / STM_SECTOR_SIZE)+1):(size / STM_SECTOR_SIZE);
	//开始录入到APP区
	for (i = 0; i < num; i++) {
		swapDownload = i*STM_SECTOR_SIZE + FLASH_DOWNLOAD;
		swapApp = i*STM_SECTOR_SIZE + FLASH_APP;
		STMFLASH_Read( swapDownload, (uint16_t *)ulBufFlashApp, 1024 );
		STMFLASH_Write ( swapApp, ulBufFlashApp, 256 );
		STMFLASH_Read( swapApp, (uint16_t *)iapbuf, 1024 );
		for(j=0;j<256;j++) {
			if(ulBufFlashApp[j] != pData[j]){
				printf("TR:%#x,Swap %#x writer and read error!\r\n",uDeviceAddr,(int)swapApp);
				break;
			}
		}
	}

}


void process_iap_senddata(cmdStruct_t *suite)
{
	uint32_t len;
	uint32_t crc32 = 0;

   //第二阶段，可以进行固件更新
	if(system_para.boot == 1)
	{
		uint32_t addr = 0, addr_next = 0;
		addr = (suite->m_Message[0] << 0) |
				(suite->m_Message[1] << 8) |
				(suite->m_Message[2] << 16) |
				(suite->m_Message[3] << 24) ;

		len = suite->m_DataLen - 4;//cmd(12)+addr(4)+(n-4)
		if(addr>0) {
			iap_write_appbin(FLASH_DOWNLOAD + addr, &suite->m_Message[4], len);
		}

		if(addr == 0) {


			replyStruct.m_DevType          = 5;  //m_DevType
			replyStruct.m_SrcDevType       = suite->m_DstDevType;        //m_SrcDevType 回包：源组件 目标组件  对调
			replyStruct.m_SrcDevNum        = suite->m_DstDevNum;        //m_SrcDevNum
			replyStruct.m_DstDevType       = suite->m_SrcDevType;        //m_DstDevType
			replyStruct.m_DstDevNum        = suite->m_SrcDevNum;        //m_DstDevNum
			replyStruct.m_CmdType          = 0;                //m_CmdType
			replyStruct.m_CmdChildType     = 3;        //m_CmdChildType
			replyStruct.m_devState         = 0;                                 //m_devState
			replyStruct.m_DataLen          =  2;                 //m_DataLen

			etwsSendto((uint8_t *)&replyStruct, replyStruct.m_DataLen + 12);

			iap_write_appbin(FLASH_DOWNLOAD + addr, &suite->m_Message[4], len);

			 crc32 = iap_appbin_check(FLASH_DOWNLOAD,system_para.size);
			 HAL_Delay(500);
			 printf("TR:%#x,Download crc32 = %x system_para.crc32 = %x system_para.size = %d\r\n",uDeviceAddr,(int)crc32 , (int)system_para.crc32 ,(int)system_para.size);

			if(crc32 == system_para.crc32) {
				iap_appbin_swap(FLASH_APP,FLASH_DOWNLOAD,system_para.size);
				crc32 = iap_appbin_check(FLASH_APP,system_para.size);
				printf("TR:%#x,Swap crc32 = %x system_para.crc32 = %x system_para.size = %d\r\n",uDeviceAddr,(int)crc32 , (int)system_para.crc32 ,(int)system_para.size);
				if(crc32 == system_para.crc32) {
					printf("TR:%#x,Download verified successfully, Jumping ...\r\n",uDeviceAddr);
					HAL_Delay(1000);
					printf("TR:%#x,start jumping !\r\n",uDeviceAddr);
#if (DEBUG == 0)
					iap_load_app(FLASH_APP);
#endif
				}
			} else {
				printf("TR:%#x,process_iap_senddata Verified failure , unJump\r\n",uDeviceAddr);
			}


		} else {
			uint32_t data_len = 0;//回复数据长度
			if(addr + len >= system_para.size)
				addr_next = 0;
			else
				addr_next = addr + len;

			replyStruct.m_Message[data_len++] 	 = addr_next & 0xff;											//预留
			replyStruct.m_Message[data_len++] 	 = addr_next>>8 & 0xff;											//版本V1.0.2
			replyStruct.m_Message[data_len++] 	 = addr_next>>16 & 0xff;
			replyStruct.m_Message[data_len++]	 = addr_next>>24 & 0xff;

			frame_header_fill(suite, data_len);

			etwsSendto((uint8_t *)&replyStruct, replyStruct.m_DataLen + 12);
		}


	}

}

void process_iap_over(cmdStruct_t *suite)
{

	printf("TR:%#x,process_iap_over\r\n",uDeviceAddr);
}

void process_iap_err(cmdStruct_t *suite)
{

	printf("TR:%#x,process_iap_err\r\n",uDeviceAddr);
}

void process_iap_log(cmdStruct_t *suite)
{

	printf("TR:%#x,process_iap_log\r\n",uDeviceAddr);
}
//确认是否进入BOOT模式
void process_iap_boot(cmdStruct_t *suite)
{
	//只是告诉上位机，进入了boot模式
	uint32_t i ;
	system_para.boot = 1;
	replyStruct.m_Message[0] = system_para.boot;//固件更新
	frame_header_fill(suite,1);
	etwsSendto((uint8_t *)&replyStruct,replyStruct.m_DataLen + 12);
	for(i=0;i<2500;i++) {
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
	}
	printf("TR:%#x,Enter boot mode.\r\n",uDeviceAddr);


}

void process_iap_reset(cmdStruct_t *suite)
{
	//暂时没用到，只是告诉上位机，进入了boot模式
	frame_header_fill(suite,0);
	etwsSendto((uint8_t *)&replyStruct,replyStruct.m_DataLen + 12);
	NVIC_SystemReset();

}


//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
{
	uint16_t us, usCtr=0, usTemp = 0,m_check = 2;
	uint32_t ulAdd_Write = appxaddr;                                //当前写入的地址
	uint64_t * pData = (uint64_t *)appbuf;
	usTemp = (appsize % 8 == 0)?(appsize / 8):(appsize / 8 + 1);//判断时候为u64整数。如果不是得多加一个u64保证全部写入成功
	memset((uint8_t *)ulBufFlashApp,0xff,sizeof(ulBufFlashApp));
	for ( us = 0; us < usTemp; us++ )
	{
		ulBufFlashApp [ usCtr ] = pData[ usCtr ];
		usCtr++;
		if ( usCtr == 256 )
		{
			usCtr = 0;
			STMFLASH_Write ( ulAdd_Write, ulBufFlashApp, 256 );
			STMFLASH_Read( ulAdd_Write, (uint16_t *)iapbuf, 1024 );
			m_check = memcmp((uint8_t *) ulBufFlashApp,iapbuf,2048);
			if(m_check != 0) {
				printf("TR:%#x,DownLoad %#x writer and read error!\r\n",uDeviceAddr,(int)ulAdd_Write);
			}
			ulAdd_Write += 2048;                                           //偏移2048  16=2*8.所以要乘以2.
			memset((uint8_t *)ulBufFlashApp,0xff,sizeof(ulBufFlashApp));
		}
	}
	if ( usCtr ) {
		//计算余下了几个字节
		uint8_t m_temp[8],m_ctr = appsize % 8,i = 0,k=0;
		uint32_t j = 0;
		memset(m_temp,0xff,8);
		for(i = m_ctr; i > 0; i--) {
			j = appsize - i;
			m_temp[k] = appbuf[j];
			k++;
		}
		if(m_ctr != 0) ulBufFlashApp[usCtr - 1] = *(uint64_t *)m_temp;
		STMFLASH_Write ( ulAdd_Write, ulBufFlashApp, usCtr );//将最后的一些内容字节写进去.
		STMFLASH_Read( ulAdd_Write, (uint16_t *)iapbuf, usCtr*4 );
		m_check = memcmp((uint8_t *) ulBufFlashApp,iapbuf,usCtr*8);
		if(m_check != 0) {
			printf("TR:%#x,DownLoad %#x writer and read error!\r\n",uDeviceAddr,(int)ulAdd_Write);
		}
	}


}

uint32_t iap_appbin_check(uint32_t appxaddr,uint32_t size)
{
	uint8_t Buf[4];
	uint32_t num;
	uint8_t  num_mod;
	uint32_t flash_val;
	uint32_t i;
	uint32_t j;
	uint32_t crc32_val = 0xffffffff;
	uint8_t k;

	num = size / 4;
	num_mod = size % 4;
	j = 0;
	for(i = 0; i < num; i++)
	{
		flash_val = ReadFlash(appxaddr + j);	//把读取STMflash内部的字，存入VAL中
		j += 4;
		Buf[3] = flash_val >> 24;
		Buf[2] = flash_val >> 16;
		Buf[1] = flash_val >> 8;
		Buf[0] = flash_val;

		for (k = 0; k < 4; k++)
		crc32_val = crc32tab[(crc32_val ^ Buf[k]) & 0xff] ^ (crc32_val >> 8);
	}
	flash_val = ReadFlash(appxaddr + j);
	Buf[3] = flash_val >> 24;
	Buf[2] = flash_val >> 16;
	Buf[1] = flash_val >> 8;
	Buf[0] = flash_val;
	if	   (0 == num_mod) crc32_val = crc32_val;
	else if(1 == num_mod) crc32_val = crc32tab[(crc32_val ^ Buf[0]) & 0xff] ^ (crc32_val >> 8);
	else if(2 == num_mod)
	{
		for (k = 0; k < 2; k++)
		crc32_val = crc32tab[(crc32_val ^ Buf[k]) & 0xff] ^ (crc32_val >> 8);
	}
	else if(3 == num_mod)
	{
		for (k = 0; k < 3; k++)
		crc32_val = crc32tab[(crc32_val ^ Buf[k]) & 0xff] ^ (crc32_val >> 8);
	}

	return crc32_val ^ 0xFFFFFFFF;
}

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(__IO uint32_t Addr)
{
    pFunction JumpToApplication;
    uint32_t JumpAddress;
    HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);
    HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
    __HAL_UART_DISABLE_IT(&huart4,UART_IT_IDLE);
    __HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE);
    // 禁用全局中断
    __disable_irq();

    // 设置跳转地址
    JumpAddress = *(__IO uint32_t*) (Addr + 4);
    JumpToApplication = (pFunction) JumpAddress;

    // 初始化堆栈指针
    __set_MSP(*(__IO uint32_t*) Addr);

    // 跳转到应用程序
    JumpToApplication();

}

/********************************Iap_end****************************************/

void process_decode(uint8_t *data,uint32_t len)
{
	if(data == NULL || len == 0)
			return ;

	int ret = 0;
	memset((uint8_t *)&cmdStruct,0,CMD_HEARD);//清除帧头
	if(len >= CMD_HEARD && len <= MAXBUFF) {
		uint8_t *uPrt = (uint8_t *)&cmdStruct;
		for(uint16_t i=0;i<len;i++)
		{
			uPrt[i] = data[i];
		}
	} else {
		//TODO:V1.3屏蔽
		return ;
	}

	if(cmdStruct.m_DataLen > MAXBUFF)
	{
		//TODO:V1.3屏蔽
//		printf("m_DataLen:%ld\r\n",cmdStruct.m_DataLen);
		return ;
	}
	ret = Check_ModbusCRC16(&cmdStruct);
	if(ret != 0)
	{
		printf("TR:%#x,crc16 error!\r\n",uDeviceAddr);
		return ;
	}
	//TODO:1V3 打印标志位移动到这里
	priFlag = 1;//打开printf打印功能
	if(cmdStruct.m_DstDevType == uDeviceType &&
	   cmdStruct.m_DstDevNum == uDeviceAddr)
	{
		uint16_t cmd_num = sizeof(fastdds_cmd)/sizeof(uint16_t)/CMD_MAX;
		uint16_t i=0;

		//解码数据
		for(i=0;i<cmd_num;i++)
		{
			if( fastdds_cmd[i][CMD_DEVICE_TYPE] == cmdStruct.m_DevType&&
					fastdds_cmd[i][CMD_CMD_TYPE] == cmdStruct.m_CmdType&&
					fastdds_cmd[i][CMD_CMD_CHILD_TYPE] == cmdStruct.m_CmdChildType)
			{
				process_decode_table[i](&cmdStruct);
				break;
			}
		}

		//解码失败
		if(i >= cmd_num)
		{
			printf("TR:%#x,decode cmd err!\r\n",uDeviceAddr);
		}
	} else { //TODO:V1.2 新增id错误后上报实际ID
		system_para.boot = 1;
		printf("Target device id is:%#x.\r\n",uDeviceAddr);
	}


}

void process_jump(void)
{
	uint32_t flash_head = 0xffffffff;
	if(system_para.boot == 0)
	{
		flash_head = ReadFlash(FLASH_APP);	//把读取STMflash内部的字，存入VAL中
		if(flash_head != 0xffffffff) {
			printf("TR:%#x,boatload jump sucessfully.\r\n",uDeviceAddr);
			iap_load_app(FLASH_APP);
		} else {
			printf("TR:%#x,boatload jump failure,apphead is 0xffff.\r\n",uDeviceAddr);
		}
	}
}

